/* ex: set tabstop=4 shiftwidth=4 expandtab: */
#ifndef _RTSP_H
#define _RTSP_H

#include <stdio.h> /* for FILE* */

#define NETAV_PORT	5999

extern char netav_host[];

struct rtsp_session;

#define CHANNEL_BUF_SIZE 4096

typedef struct rtsp_channel {
	struct rtsp_session *session;
	int fd; /* socket */
	int len; /* len of buf */
	char buf[CHANNEL_BUF_SIZE];
} rtsp_channel_t;

#define RTSP_S_CLOSE	0
#define RTSP_S_INIT		1
#define RTSP_S_READY	2
#define RTSP_S_PLAYING	3

#define RTSP_T_CONN		0
#define RTSP_T_LFXMSG	1

typedef struct rtsp_session {
	int state; /* RTSP_S_* */
	int type; /* RTSP_T_* */

	rtsp_channel_t *chn_get;
	rtsp_channel_t *chn_post;
	FILE *fp; /* handle to video file */
} rtsp_session_t;

/*
 * psudo-code for rtsp session life-cycle
 *
 * initialize 2 rtsp_sessions, one for CONNECT, another for LFXMSG.
 *
 * bind and listen
 * accept opens a channel, ch. Initialize ch's buffer and fd.
 *
 * the first request of a socket is always a GET with path /messageX,
 * where X can be 0, 1, 2 or 3.
 * if X is 0, returns HTTP 401, otherwise HTTP 200.
 *
 * the 2nd request can be one of these:
 * GET /connect -> bind it to session CONNECT as chn_get
 * POST /connect -> bind it to session CONNECT as chn_post
 * GET /lfxmsg -> bind it to session LFXMSG as chn_get
 * POST /lfxmsg -> bind it to session LFXMSG as chn_post
 *
 * if any other request is received, close fd and free channel.
 *
 * once all 4 channels are bound to its session, mark session to INIT state.
 * if session is not at CLOSE state, all incoming request will be denied.
 *
 * chn_post is ready for receiving from client, while che_get is ready for
 * sending to client.
 * note that chn_post is expected to receive base64 decoded messages.
 */

extern void rtsp_init(void);

/* called from select loop to create new channel.
 * return 0 on success, -1 on failure
 * it fails if session is not in CLOSE state, i.e.,
 * when all 4 channels are setup already
 */
extern int open_channel(int fd);

/* called from select loop when a fd has sth. to read.
 * return 0 on success, -1 on failure.
 * -1 will cause select loop to remove the fd from fd_set
 * and close the fd.
 */
extern int channel_read(int fd, void *arg);

#endif
